#include "EntityManager.h"

int EntityManager::nextID = 0;
EntityManager* EntityManager::instance = 0;
std::map<int, Entity*> EntityManager::entities = std::map<int, Entity*>();
std::map<std::string, std::list<Entity*>> EntityManager::namedEntities = std::map<std::string, std::list<Entity*>>();


EntityManager::EntityManager()
{
}

EntityManager::~EntityManager()
{
	auto iter = entities.begin();
	for (; iter != entities.end(); iter++)
	{
		delete iter->second;
		iter->second = 0;
	}
	entities.clear();
}

void EntityManager::init()
{
	EntityManager::instance = new EntityManager();
}

void EntityManager::update(float frameTime)
{
	auto iter = entities.begin();
	for (; iter != entities.end(); iter++)
	{
		iter->second->update(frameTime);
	}
}

void EntityManager::draw(ID3DXSprite *sprite)
{
	auto iter = entities.begin();
	for (; iter != entities.end(); iter++)
	{
		iter->second->draw(sprite);
	}
}

void EntityManager::registerEntity(Entity* entity)
{
	if (entity->getID() == -1)
	{
		while (entities.find(EntityManager::nextID) != entities.end())
			++EntityManager::nextID;

		entity->setID(nextID);
	}
	else if (entities.find(entity->getID()) != entities.end())
		throw; // Entity of ID exists. Throw exception

	entities[entity->getID()] = entity;

	if(entity->getName() != "")
	{
		auto iter = namedEntities.find(entity->getName());
		if(iter == namedEntities.end())
		{
          //List doesn't exist. Add a new list and add the entity to it
			std::list<Entity*> entities;
			entities.push_back(entity);
			namedEntities[entity->getName()] = entities;
		}
		else
		{
           //Add to existing list
			iter->second.push_back(entity);
		}
	} 
}

void EntityManager::removeEntity(Entity *entity)
{
	auto iter = entities.find(entity->getID());
	if (iter != entities.end())
		entities.erase(iter);
	if(entity->getName() != "")
	{
       //Find the list of entities, and remove this Entity from it.
		std::map<std::string, std::list<Entity*>>::iterator iter = namedEntities.find(entity->getName());
		iter->second.remove(entity);
	}
}

Entity* EntityManager::getEntity(int id)
{
	auto iter = entities.find(id);
	if (iter != entities.end())
		return iter->second;
	return 0;
}

//Try to find the list of Entities of the given name, and if we find we create
//a reference to it and then return the reference. Otherwise we create empty list and return that

std::list<Entity*>* EntityManager::getNamedEntities(std::string name)
{
	auto iter = namedEntities.find(name);
	if (iter != namedEntities.end())
		return &(iter->second);
	else 
		return 0;
}